{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "lang": "en",
    "tags": [
     "parameters"
    ]
   },
   "outputs": [],
   "source": [
    "epochs = 10"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "# भाग 6 - CNN वापरुन MNIST वर फेडरटेड लर्निंग\n",
    "\n",
    "##  PyTorch + PySyft च्या 10 ओळींमध्ये फेडरेटेड लर्निंगवर श्रेणीसुधारित करा\n",
    "\n",
    "\n",
    "### संदर्भ\n",
    "\n",
    "फेडरटेड लर्निंग हे एक अतिशय रोमांचक आणि अप्सर्जिंग मशीन लर्निंग तंत्र आहे ज्याच उद्दीष्ट असे सिस्टम प्रणाली बनवायचे आहे जे विकेंद्रित डेटावर शिकेल. अशी कल्पना आहे की डेटा त्याच्या उत्पादकाच्या हातात आहे (ज्यास कामगार म्हणून देखील ओळखले जाते), जी गोपनीयता आणि मालकी सुधारण्यात मदत करते आणि हे मॉडेल कामगारांमध्ये सामायिक केले जाते. एक त्वरित अनुप्रयोग म्हणजे आपण मजकूर लिहिता तेव्हा आपल्या मोबाइल फोनवर पुढील शब्दाचा अंदाज लावणे: आपल्याला आपला डेटा प्रशिक्षणासाठी वापरलेला नको असतो - म्हणजे आपले मजकूर संदेश - मध्यवर्ती सर्व्हरला पाठवावे लागते.\n",
    "\n",
    "फेडरटेड लर्निंगचा उदय डेटा गोपनीयता जागरूकता पसरवण्यासाठी घट्टपणे जोडलेला आहे आणि मे 2018 पासून डेटा संरक्षणची अंमलबजावणी करणारी EU मधील GDPR ने उत्प्रेरक म्हणून काम केले आहे. नियमांची अपेक्षा करण्यासाठी, Apple किंवा Google सारख्या मोठ्या कलाकारांनी या तंत्रज्ञानामध्ये, विशेषत: मोबाइल वापरकर्त्यांच्या गोपनीयतेचे रक्षण करण्यासाठी मोठ्या प्रमाणात गुंतवणूक सुरू केली आहे, परंतु त्यांनी त्यांची साधने उपलब्ध केली नाहीत. Openmined मध्ये आमचा विश्वास आहे की मशीन लर्निंग प्रोजेक्ट घेण्यास इच्छुक असलेल्या कोणालाही अगदी थोड्या प्रयत्नातून गोपनीयता संरक्षणाची साधने लागू करण्यास सक्षम असावे. [आमच्या ब्लॉग पोस्टमध्ये नमूद केल्यानुसार](https://blog.openmined.org/training-cnns-use-spdz/) आम्ही एका ओळीत डेटा कूटबद्ध करण्यासाठी साधने तयार केली आहेत आणि आम्ही आता आमची फेडरेटेड लर्निंग फ्रेमवर्क रीलिझ केली आहे जी सुरक्षित आणि स्केलेबल मॉडेल तयार करण्यासाठी अंतर्ज्ञानी इंटरफेस प्रदान करण्यासाठी नवीन PyTorch 1.0 आवृत्तीचा लाभ घेते.\n",
    "\n",
    "या ट्युटोरियलमध्ये आपण [PyTorch चा वापर करून CNN ला MNIST वर प्रशिक्षण देण्याचे थेट उदाहरण](https://github.com/pytorch/examples/blob/master/mnist/main.py) वापरू आणि आमच्या [PySyft लायब्ररीच्या](https://github.com/OpenMined/PySyft/) सहाय्याने फेडरेट लर्निंगची अंमलबजावणी करणे किती सोपे आहे हे दर्शवू. आम्ही उदाहरणाच्या प्रत्येक भागावर जाऊ आणि बदललेला कोड अधोरेखित करू.\n",
    "\n",
    "आपण [आमच्या ब्लॉगपोस्टमध्ये] (https://blog.openmined.org/upgrad-to-federated-learning-in-10-lines) ही सामग्री देखील शोधू शकता.\n",
    "\n",
    "लेखक:\n",
    "- Théo Ryffel - GitHub: [@LaRiffle](https://github.com/LaRiffle)\n",
    "\n",
    "अनुवादक/संपादक:\n",
    "- Krunal Kshirsagar - Twitter: [@krunal_wrote](https://twitter.com/krunal_wrote)· Github: [@Noob-can-Compile](https://github.com/Noob-can-Compile)\n",
    "\n",
    "\n",
    "**ठीक आहे, चला तर मग सुरू करूया!**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "### आयात आणि मॉडेल वैशिष्ट्ये\n",
    "\n",
    "प्रथम आपण अधिकृत आयात करतो"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "import torch.optim as optim\n",
    "from torchvision import datasets, transforms"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "आणि PySyft मध्ये विशिष्ट त्यापेक्षा विशेषतः आपण दूरस्थ कामगारांना `आलिस`(`alice`) आणि `बॉब`(`bob`) परिभाषित करतो."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import syft as sy  # <-- NEW: import the Pysyft library\n",
    "hook = sy.TorchHook(torch)  # <-- NEW: hook PyTorch ie add extra functionalities to support Federated Learning\n",
    "bob = sy.VirtualWorker(hook, id=\"bob\")  # <-- NEW: define remote worker bob\n",
    "alice = sy.VirtualWorker(hook, id=\"alice\")  # <-- NEW: and alice"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "आपण शिकण्याच्या कार्याची(learning task) सेटिंग परिभाषित करतो"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Arguments():\n",
    "    def __init__(self):\n",
    "        self.batch_size = 64\n",
    "        self.test_batch_size = 1000\n",
    "        self.epochs = epochs\n",
    "        self.lr = 0.01\n",
    "        self.momentum = 0.5\n",
    "        self.no_cuda = False\n",
    "        self.seed = 1\n",
    "        self.log_interval = 30\n",
    "        self.save_model = False\n",
    "\n",
    "args = Arguments()\n",
    "\n",
    "use_cuda = not args.no_cuda and torch.cuda.is_available()\n",
    "\n",
    "torch.manual_seed(args.seed)\n",
    "\n",
    "device = torch.device(\"cuda\" if use_cuda else \"cpu\")\n",
    "\n",
    "kwargs = {'num_workers': 1, 'pin_memory': True} if use_cuda else {}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### डेटा लोड करणे आणि कामगारांना(workers) पाठवणे\n",
    "आपण  प्रथम डेटा लोड करतो आणि प्रशिक्षण डेटासेटला `.federate`  method वापरुन कामगारांमध्ये फेडरेटेड डेटासेट स्प्लिट करतो. हा फेडरेटेड डेटासेट आता फेडरेट डेटालोडरला देण्यात आला आहे. चाचणी डेटासेट(Test Dataset) अपरिवर्तित आहे."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "federated_train_loader = sy.FederatedDataLoader( # <-- this is now a FederatedDataLoader \n",
    "    datasets.MNIST('../data', train=True, download=True,\n",
    "                   transform=transforms.Compose([\n",
    "                       transforms.ToTensor(),\n",
    "                       transforms.Normalize((0.1307,), (0.3081,))\n",
    "                   ]))\n",
    "    .federate((bob, alice)), # <-- NEW: we distribute the dataset across all the workers, it's now a FederatedDataset\n",
    "    batch_size=args.batch_size, shuffle=True, **kwargs)\n",
    "\n",
    "test_loader = torch.utils.data.DataLoader(\n",
    "    datasets.MNIST('../data', train=False, transform=transforms.Compose([\n",
    "                       transforms.ToTensor(),\n",
    "                       transforms.Normalize((0.1307,), (0.3081,))\n",
    "                   ])),\n",
    "    batch_size=args.test_batch_size, shuffle=True, **kwargs)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "### सीएनएन (CNN) तपशील\n",
    "येथे आपण अधिकृत उदाहरणांप्रमाणेच सीएनएन (CNN) वापरतो."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Net(nn.Module):\n",
    "    def __init__(self):\n",
    "        super(Net, self).__init__()\n",
    "        self.conv1 = nn.Conv2d(1, 20, 5, 1)\n",
    "        self.conv2 = nn.Conv2d(20, 50, 5, 1)\n",
    "        self.fc1 = nn.Linear(4*4*50, 500)\n",
    "        self.fc2 = nn.Linear(500, 10)\n",
    "\n",
    "    def forward(self, x):\n",
    "        x = F.relu(self.conv1(x))\n",
    "        x = F.max_pool2d(x, 2, 2)\n",
    "        x = F.relu(self.conv2(x))\n",
    "        x = F.max_pool2d(x, 2, 2)\n",
    "        x = x.view(-1, 4*4*50)\n",
    "        x = F.relu(self.fc1(x))\n",
    "        x = self.fc2(x)\n",
    "        return F.log_softmax(x, dim=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### प्रशिक्षित(Train) आणि चाचणी(Test) कार्ये परिभाषित करा\n",
    "\n",
    "प्रशिक्षित कार्यासाठी, डेटा बॅचेस `alice` और `bob` वितरित केल्यामुळे, आपल्याला प्रत्येक बॅचसाठी मॉडेल योग्य ठिकाणी पाठविणे आवश्यक आहे. नंतर आपण स्थानिक PyTorch करीत असलेल्या सारख्याच वाक्यरचनासह आपण सर्व ऑपरेशन दूरस्थपणे करतो. आपण कार्य पूर्ण केल्यावर, आपल्याला अद्यतनित (updated) केले मॉडेल आणि सुधारणासाठी शोधलेले नुकसान(loss)परत मिळते."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def train(args, model, device, federated_train_loader, optimizer, epoch):\n",
    "    model.train()\n",
    "    for batch_idx, (data, target) in enumerate(federated_train_loader): # <-- now it is a distributed dataset\n",
    "        model.send(data.location) # <-- NEW: send the model to the right location\n",
    "        data, target = data.to(device), target.to(device)\n",
    "        optimizer.zero_grad()\n",
    "        output = model(data)\n",
    "        loss = F.nll_loss(output, target)\n",
    "        loss.backward()\n",
    "        optimizer.step()\n",
    "        model.get() # <-- NEW: get the model back\n",
    "        if batch_idx % args.log_interval == 0:\n",
    "            loss = loss.get() # <-- NEW: get the loss back\n",
    "            print('Train Epoch: {} [{}/{} ({:.0f}%)]\\tLoss: {:.6f}'.format(\n",
    "                epoch, batch_idx * args.batch_size, len(federated_train_loader) * args.batch_size,\n",
    "                100. * batch_idx / len(federated_train_loader), loss.item()))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "चाचणी कार्य बदलत नाही!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def test(args, model, device, test_loader):\n",
    "    model.eval()\n",
    "    test_loss = 0\n",
    "    correct = 0\n",
    "    with torch.no_grad():\n",
    "        for data, target in test_loader:\n",
    "            data, target = data.to(device), target.to(device)\n",
    "            output = model(data)\n",
    "            test_loss += F.nll_loss(output, target, reduction='sum').item() # sum up batch loss\n",
    "            pred = output.argmax(1, keepdim=True) # get the index of the max log-probability \n",
    "            correct += pred.eq(target.view_as(pred)).sum().item()\n",
    "\n",
    "    test_loss /= len(test_loader.dataset)\n",
    "\n",
    "    print('\\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\\n'.format(\n",
    "        test_loss, correct, len(test_loader.dataset),\n",
    "        100. * correct / len(test_loader.dataset)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "### प्रशिक्षण सुरू करा!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%time\n",
    "model = Net().to(device)\n",
    "optimizer = optim.SGD(model.parameters(), lr=args.lr) # TODO momentum is not supported at the moment\n",
    "\n",
    "for epoch in range(1, args.epochs + 1):\n",
    "    train(args, model, device, federated_train_loader, optimizer, epoch)\n",
    "    test(args, model, device, test_loader)\n",
    "\n",
    "if (args.save_model):\n",
    "    torch.save(model.state_dict(), \"mnist_cnn.pt\")\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Et voilà! आपण येथे पोहोचलात, आपण फेडरेटेड लर्निंगचा वापर करून दूरस्थ डेटावर मॉडेलचे प्रशिक्षण दिले आहे!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## एक शेवटची गोष्ट\n",
    "मला माहित आहे की आपल्या मनात असा प्रश्न आला असणार : ** सामान्य PyTorch च्या  तुलनेत फेडरेटेड लर्निंग करण्यास किती वेळ लागतो? **\n",
    "\n",
    "संगणनाची वेळ प्रत्यक्षात ** सामान्य PyTorch ची अंमलबजावणीसाठी वापरलेल्या वेळेपेक्षा दुपटीने कमी आहे!** अधिक स्पष्टपणे सांगायचे तर, हे 1.9 पट जास्त वेळ घेते, जे आम्ही जोडण्यास सक्षम असलेल्या वैशिष्ट्यांच्या तुलनेत फारच कमी आहे."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "## निष्कर्ष\n",
    "\n",
    "आपण निरीक्षण केल्यानुसार, आपण MNIST वरील अधिकृत PyTorch च उदाहरण वास्तविक फेडरेट लर्निंग सेटिंगमध्ये श्रेणीसुधारित करण्यासाठी कोडच्या 10 ओळी सुधारित केल्या.\n",
    "\n",
    "नक्कीच, आपण विचार करू शकू अशा अनेक डझनभर सुधारणा आहेत. आपण कामगारांना समांतर कार्य करण्यासाठी आणि फेडरेटेड सरासरी कामगिरी करण्यासाठी, केवळ प्रत्येक `n` बॅचेसचे केंद्रीय मॉडेल अद्यतनित करणे, कामगारांमधील संप्रेषणासाठी आपण वापरत असलेल्या संदेशांची संख्या कमी करण्यासाठी इत्यादी गणना करू इच्छितो. ही वैशिष्ट्ये आहेत ज्याचावर आम्ही कार्य करीत आहोत. फेडरेटेड लर्निंगला उत्पादनाच्या वातावरणासाठी तयार करण्याचे काम आम्ही करीत आहोत आणि ते प्रसिद्ध होताच आम्ही त्यांच्याबद्दल लिहू!\n",
    "\n",
    "आपण आता स्वत: हून फेडरेटेड लर्निंग करण्यास सक्षम असावेत! आपण याचा आनंद घेत असल्यास आणि एआय आणि एआय सप्लाय चेन (डेटा) च्या विकेंद्रित मालकीच्या गोपनीयतेच्या संरक्षणाच्या दिशेने चळवळीत सामील होऊ इच्छित असाल तर आपण हे खालील प्रकारे करू शकता!\n",
    "\n",
    "### Pysyft ला Github वर Star करा!\n",
    "\n",
    "आमच्या समुदायाला मदत करण्याचा सर्वात सोपा मार्ग म्हणजे फक्त गिटहब(GitHub) रेपो(Repo) तारांकित(Star) करणे! हे आम्ही तयार करीत असलेल्या छान साधनांविषयी जागरूकता वाढविण्यास मदत करते.\n",
    "\n",
    "- [Star PySyft](https://github.com/OpenMined/PySyft)\n",
    "\n",
    "### GitHub वरील आमचे प्रशिक्षण निवडा.\n",
    "\n",
    "आम्ही फेडरेटेड आणि गोपनीयता-संरक्षित लर्निंगबद्दल अधिक चांगल्या प्रकारे समजवण्यासाठी खरोखर चांगले ट्यूटोरियल बनवले आहेत.\n",
    "\n",
    "- [PySyft ट्यूटोरियल्सला चेक करा](https://github.com/OpenMined/PySyft/tree/master/examples/tutorials)\n",
    "\n",
    "### आमच्या Slack मध्ये सामील व्हा!\n",
    "\n",
    "\n",
    "नवीनतम प्रगतीवर अद्ययावत राहण्याचा उत्तम मार्ग म्हणजे आमच्या समुदायामध्ये सामील होणे! आपण [http://slack.openmined.org](http://slack.openmined.org) येथे फॉर्म भरुन तसे करू शकता.\n",
    "\n",
    "### एका कोड प्रोजेक्टमध्ये सामील व्हा!\n",
    "\n",
    "आमच्या समुदायामध्ये योगदानाचा उत्तम मार्ग म्हणजे कोड योगदानकर्ता बनणे! कोणत्याही वेळी आपण (PySyft GitHub Issues Page) वर  जाऊ शकता आणि \"Project\" साठी फिल्टर करू शकता. हे आपण कोणत्या प्रकल्पांमध्ये सामील होऊ शकता याबद्दल विहंगावलोकन देणारी सर्व उच्च स्तरीय तिकिटे दर्शवेल! आपण एखाद्या प्रकल्पात सामील होऊ इच्छित नसल्यास, परंतु आपण थोडं कोडिंग करू इच्छित असाल तर आपण \"good first issues\" म्हणून चिन्हांकित गिटहब(GitHub) अंक शोधून आणखी \"one off\" मिनी-प्रकल्प(mini project) शोधू शकता.\n",
    "\n",
    "- [PySyft Projects](https://github.com/OpenMined/PySyft/issues?q=is%3Aopen+is%3Aissue+label%3AProject)\n",
    "- [Good First Issue Tickets](https://github.com/OpenMined/PySyft/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)\n",
    "\n",
    "### दान करा\n",
    "\n",
    "आपल्याकडे आमच्या कोडेबेसमध्ये योगदान देण्यास वेळ नसल्यास, परंतु तरीही आपल्याला समर्थन द्यावयाचे असल्यास आपण आमच्या मुक्त संग्रहात बॅकर देखील होऊ शकता. सर्व देणगी आमच्या वेब होस्टिंग आणि हॅकॅथॉन आणि मेटअप्स सारख्या इतर सामुदायिक खर्चाकडे जातात!\n",
    "\n",
    "[OpenMined's Open Collective Page](https://opencollective.com/openmined)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "celltoolbar": "Tags",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  },
  "nbTranslate": {
   "displayLangs": [
    "hi"
   ],
   "hotkey": "alt-t",
   "langInMainMenu": true,
   "sourceLang": "en",
   "targetLang": "hi",
   "useGoogleTranslate": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}